#ifndef THRUMASTERROCKER_H
#define THRUMASTERROCKER_H

#include <hidapi.h>
#include <QObject>
#include <QThread>

class ThrumasterRocker : public QObject
{
    Q_OBJECT
    Q_PROPERTY(ButtonState button1 READ button1 WRITE setButton1 NOTIFY button1Changed FINAL)
    Q_PROPERTY(ButtonState button2 READ button2 WRITE setButton2 NOTIFY button2Changed FINAL)
    Q_PROPERTY(ButtonState button3 READ button3 WRITE setButton3 NOTIFY button3Changed FINAL)
    Q_PROPERTY(TriggerState trigger1 READ trigger1 WRITE setTrigger1 NOTIFY trigger1Changed FINAL)
    Q_PROPERTY(TriggerState trigger2 READ trigger2 WRITE setTrigger2 NOTIFY trigger2Changed FINAL)
    Q_PROPERTY(AxisState axis4 READ axis4 WRITE setAxis4 NOTIFY axis4Changed FINAL)
    Q_PROPERTY(AxisState axis5 READ axis5 WRITE setAxis5 NOTIFY axis5Changed FINAL)
    Q_PROPERTY(AxisState axis81 READ axis81 WRITE setAxis81 NOTIFY axis81Changed FINAL)
    Q_PROPERTY(AxisState axis82 READ axis82 WRITE setAxis82 NOTIFY axis82Changed FINAL)
    Q_PROPERTY(double rockerX READ rockerX WRITE setRockerX NOTIFY rockerXChanged FINAL)
    Q_PROPERTY(double rockerY READ rockerY WRITE setRockerY NOTIFY rockerYChanged FINAL)

public:
    enum AxisState {        // axis控件的状态
        Axis_RELEASE,
        Axis_UP,
        Axis_DOWN,
        Axis_LEFT,
        Axis_RIGHT,
        Axis_LEFT_UP,
        Axis_LEFT_DOWN,
        Axis_RIGHT_UP,
        Axis_RIGHT_DOWN,
        Axis_PRESSED
    };
    Q_ENUM(AxisState)

    enum ButtonState {      // button控件的状态
        Button_RELEASE,
        Button_PUSHED
    };
    Q_ENUM(ButtonState)

    enum TriggerState {     // trigger控件的状态
        Trigger_RELEASE,
        Trigger_PUSHED
    };
    Q_ENUM(TriggerState)

public:
    explicit ThrumasterRocker(QObject *parent = nullptr);
    ~ThrumasterRocker();

    Q_INVOKABLE void readRawData();

    ButtonState button1() const;
    void setButton1(ButtonState newButton1);

    ButtonState button2() const;
    void setButton2(ButtonState newButton2);

    ButtonState button3() const;
    void setButton3(ButtonState newButton3);

    TriggerState trigger1() const;
    void setTrigger1(TriggerState newTrigger1);

    TriggerState trigger2() const;
    void setTrigger2(TriggerState newTrigger2);

    AxisState axis4() const;
    void setAxis4(AxisState newAxis4);

    AxisState axis5() const;
    void setAxis5(AxisState newAxis5);

    AxisState axis81() const;
    void setAxis81(AxisState newAxis81);

    AxisState axis82() const;
    void setAxis82(AxisState newAxis82);

    double rockerX() const;
    void setRockerX(double newRockerX);

    double rockerY() const;
    void setRockerY(double newRockerY);

private:
    void parseButtons(unsigned char data[], int n);
    void parseTriggers(unsigned char data[], int n);
    void parseAxis4(unsigned char data[], int n);
    void parseAxis5(unsigned char data[], int n);
    void parseAxis81(unsigned char data[], int n);
    void parseAxis82(unsigned char data[], int n);
    void parseRocker(unsigned char data[], int n);

signals:
    void button1Changed();

    void button2Changed();

    void button3Changed();

    void trigger1Changed();

    void trigger2Changed();

    void axis4Changed();

    void axis5Changed();

    void axis81Changed();

    void axis82Changed();

    void rockerXChanged();

    void rockerYChanged();

private:
    hid_device *device;

    ButtonState m_button1;
    ButtonState m_button2;
    ButtonState m_button3;
    TriggerState m_trigger1;
    TriggerState m_trigger2;
    AxisState m_axis4;
    AxisState m_axis5;
    AxisState m_axis81;
    AxisState m_axis82;
    double m_rockerX;
    double m_rockerY;
};

class ThrumasterRockerThread: public QThread
{
    Q_OBJECT

public:
    explicit ThrumasterRockerThread(ThrumasterRocker* thrumasterRocker, QObject *parent = nullptr)
        : QThread(parent),m_thrumasterRocker(thrumasterRocker) {};

protected:
    void run() override {
        while(!isInterruptionRequested()) {
            m_thrumasterRocker->readRawData();
        }
    }

private:
    ThrumasterRocker* m_thrumasterRocker;
};

#endif // THRUMASTERROCKER_H
